#pragma once
#include"SkipList.hpp"
#include"unordered_map.hpp"

namespace redisStruct
{
	class ZsetObject:redisObject
	{
	
	private:
		unordered_map<stringObject*, int> _map;
		Skiplist _skiplist;
	public:
		ZsetObject() :redisObject(TYPE_ZSET, TYPE_Encoding_SKIPLIST)
		{}

		void insert(int score, stringObject* str)
		{
			auto ret = _map.find(str);
			if (ret != _map.end()) return;

			_map.insert({ str,score });
			_skiplist.add(score, str);
		}
		size_t size() const
		{
			return _map.size();
		}

		int zcount(int min, int max) const //计算分数在【min,max】成员数
		{
			SkiplistNode* begin = nullptr;
			//找跳表中分数在【min,max】的最小值节点
			for (int i = min; i <= max; i++)
			{
				if ((begin = _skiplist.search(i)) != nullptr)
					break;
			}
			//没有
			if (begin == nullptr) return 0;

			int count = 0;
			while (begin && begin->_key <= max)
			{
				begin = begin->_next[0];
				count++;
			}

			return count;
		}

		bool zincrby(stringObject* str, int incr) //对指定成员的分数加上增量 increment
		{
			auto ret = _map.find(str);
			if (ret == _map.end()) return false;

			_skiplist.erase(ret->second);
			_skiplist.add(ret->second + incr,str);

			ret->second += incr;
		}

		vector<pair<int,stringObject*>> zrange(int lindex, int rindex)//通过索引下标返回
		{
			auto begin = _skiplist.begin()->_next[0];
			vector<pair<int, stringObject*>> ret;

			int index = 0;
			while (index < lindex && begin != nullptr)
			{
				index++;
				begin = begin->_next[0];
			}

			while (index <= rindex && begin != nullptr)
			{
				ret.push_back({ begin->_key,begin->_val });
				index++;
				begin = begin->_next[0];
			}

			return ret;
		}

		vector<pair<int, stringObject*>> zrangeByscore(int lscore, int rscore)//通过分数返回
		{
			SkiplistNode* begin = nullptr;
			//找跳表中分数在【min,max】的最小值节点
			for (int i = lscore; i <= rscore; i++)
			{
				if ((begin = _skiplist.search(i)) != nullptr)
					break;
			}
			//没有
			if (begin == nullptr) return vector<pair<int, stringObject*>>();

			vector<pair<int, stringObject*>> ret;
			while (begin && begin->_key <= rscore)
			{
				ret.push_back({ begin->_key,begin->_val });
				begin = begin->_next[0];
 			}

			return ret;
		}
		int zrank(stringObject* str) const  //返回有序集合中指定成员的索引  不存在则返回-1
		{
			auto begin = _skiplist.begin()->_next[0];
			int index = 0;
			while (begin  &&  *str != *(begin->_val))
			{
				begin = begin->_next[0];
				index++;
			}

			if (begin == nullptr) return -1;
			else return index;
		}

		void zrem( const vector<stringObject*>& rmobjs) //移除一个或多个成员 
		{
			if (rmobjs.empty()) return;

			auto ret = _map.find(rmobjs[0]);
			for (auto* strobj : rmobjs)
			{
				ret = _map.find(strobj);
				if (ret == _map.end()) continue;

				_skiplist.erase(ret->second);
				_map.erase(strobj);
			}
		}

		pair<int,bool> zscore(stringObject* str) //集合成员的分数值
		{
			auto ret = _map.find(str);
			if (ret != _map.end())
				return make_pair(ret->second, true);
			else
				return make_pair(1, false);
		}
	};

}